package top.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import top.api.Constants.SystemConstants;
import top.api.common.ResponseResult;
import top.api.domain.dto.UserAddDto;
import top.api.domain.dto.UserUpdateDto;
import top.api.domain.entity.Role;
import top.api.domain.entity.User;
import top.api.domain.entity.UserRole;
import top.api.domain.vo.*;
import top.api.enums.AppHttpCodeEnum;
import top.api.exception.SystemException;
import top.api.mapper.RoleMapper;
import top.api.service.RoleService;
import top.api.service.UserRoleService;
import top.api.service.UserService;
import top.api.mapper.UserMapper;
import org.springframework.stereotype.Service;
import top.api.utils.BeanCopyUtils;
import top.api.utils.SecurityUtils;

import java.util.ArrayList;
import java.util.List;

/**
* @author 27465
* @description 针对表【sys_user(用户表)】的数据库操作Service实现
* @createDate 2023-01-29 17:43:43
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleMapper roleMapper;

    @Override
    public ResponseResult userInfo() {
        // 查询用户信息
        Long userId = SecurityUtils.getUserId();

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId,userId);

        User user = userMapper.selectOne(queryWrapper);

        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(user, UserInfoVo.class);

        return ResponseResult.okResult(userInfoVo);
    }

    @Override
    public ResponseResult updateUserInfo(User user) {
        try {
            // 修改指定字段
            LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(User::getAvatar,user.getAvatar());
            updateWrapper.set(User::getEmail,user.getEmail());
            updateWrapper.set(User::getNickName,user.getNickName());
            updateWrapper.set(User::getSex,user.getSex());

            // 从jwt中获取userId避免伪造
            Long userId = SecurityUtils.getUserId();
            user.setId(userId);
            updateWrapper.eq(User::getId,userId);

            // 使用mapper会把所有字段进行更改
            super.update(updateWrapper);

            return ResponseResult.okResult();

        } catch (Exception e) {
            // 避免空指针
            throw new SystemException(AppHttpCodeEnum.SYSTEM_ERROR);
        }
    }

    @Override
    public ResponseResult register(User user) {
        // 非空校验 and 相同用户名校验
        registerCheck(user);

        // 对密码加密
        String pwdEncode = passwordEncoder.encode(user.getPassword());

        // 净化数据
        User _user = new User();
        _user.setUserName(user.getUserName());
        _user.setPassword(pwdEncode);
        _user.setNickName(user.getNickName());
        _user.setEmail(user.getEmail());

        // 保存
        userMapper.insert(_user);

        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getUserList(Integer pageNum, Integer pageSize, String userName, String phonenumber,String status) {
        // 查询全部用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(userName),User::getUserName,userName);
        queryWrapper.eq(StringUtils.hasText(phonenumber),User::getPhonenumber,phonenumber);
        queryWrapper.eq(StringUtils.hasText(status),User::getStatus,status);

        // 分页
        Page<User> pageInfo = new Page<>(pageNum,pageSize);
        page(pageInfo,queryWrapper);

        // 封装vo
        List<UserListVo> userListVos = BeanCopyUtils.copyBeanList(pageInfo.getRecords(), UserListVo.class);

        PageVo pageVo = new PageVo(userListVos,pageInfo.getTotal());

        return ResponseResult.okResult(pageVo);
    }

    @Override
    @Transactional
    public ResponseResult addUser(UserAddDto userAddDto) {
        User user = BeanCopyUtils.copyBean(userAddDto, User.class);
        // 非空校验 and 相同用户名校验
        registerCheck(user);

        // 对密码加密
        String pwdEncode = passwordEncoder.encode(user.getPassword());

        user.setPassword(pwdEncode);

        // 保存用户
        userMapper.insert(user);

        // 绑定角色权限
        List<UserRole> userRoles = new ArrayList<>();
        for (Integer roleId : userAddDto.getRoleIds()) {
            userRoles.add(new UserRole(user.getId(),roleId.longValue()));
        }

        userRoleService.saveBatch(userRoles);


        return ResponseResult.okResult();
    }

    @Override
    @Transactional
    public ResponseResult deleteUsers(List<Long> ids) {
        // 将用户伪删除
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(User::getId,ids);

        updateWrapper.set(User::getDelFlag, SystemConstants.DelFlagNO);

        super.update(updateWrapper);
        // 删除绑定的角色信息
        userRoleService.removeByIds(ids);

        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getUserInfo(Long id) {
        // 查询用户信息
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId,id);
        User user = userMapper.selectOne(queryWrapper);
        if (ObjectUtils.isEmpty(user)){
            return ResponseResult.errorResult(AppHttpCodeEnum.USER_IS_NULL);
        }
        // 查询用户绑定的角色id
        LambdaQueryWrapper<UserRole> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(UserRole::getUserId,id);
        List<UserRole> userRoles = userRoleService.list(queryWrapper1);
        // 查询所有的角色信息
        LambdaQueryWrapper<Role> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(Role::getStatus,SystemConstants.ROLE_STATUS_NORMAL);
        List<Role> roles = roleMapper.selectList(queryWrapper2);
        // 封装vo
        List<String> roleIds = new ArrayList<>();
        for (UserRole role : userRoles) {
            roleIds.add(role.getRoleId().toString());
        }
        List<RoleVo> roleVos = BeanCopyUtils.copyBeanList(roles, RoleVo.class);
        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(user, UserInfoVo.class);
        AdminUserAndRoleVo adminUserAndRoleVo = new AdminUserAndRoleVo(roleIds,roleVos,userInfoVo);

        return ResponseResult.okResult(adminUserAndRoleVo);
    }

    @Override
    public ResponseResult AdminUpdateUserInfo(UserUpdateDto userUpdateDto) {
        // 修改指定字段
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(User::getEmail,userUpdateDto.getEmail());
        updateWrapper.set(User::getNickName,userUpdateDto.getNickName());
        updateWrapper.set(User::getSex,userUpdateDto.getSex());
        updateWrapper.set(User::getStatus,userUpdateDto.getStatus());
        updateWrapper.set(User::getUserName,userUpdateDto.getUserName());
        updateWrapper.eq(userUpdateDto.getId()!=null,User::getId,userUpdateDto.getId());

        super.update(updateWrapper);

        // 修改用户绑定的角色  先删除在添加
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(userUpdateDto.getId()!=null,UserRole::getUserId,userUpdateDto.getId());

        userRoleService.remove(queryWrapper);

        // 写入
        List<UserRole> userRoleList = new ArrayList<>();
        for (Integer roleId : userUpdateDto.getRoleIds()) {
            userRoleList.add(new UserRole(userUpdateDto.getId(),roleId.longValue()));
        }
        userRoleService.saveBatch(userRoleList);

        return ResponseResult.okResult();

    }

    /**
     * 检查参数是否合格
     * @param user
     * @return
     */
    private void registerCheck(User user){
        if (! StringUtils.hasText(user.getUserName())){
            throw new SystemException(AppHttpCodeEnum.USERNAME_NOT_NULL);
        }else if (! StringUtils.hasText(user.getPassword()) || user.getPassword().length() < 6){
            throw new SystemException(AppHttpCodeEnum.PASSWORD_NOT_NULL);
        }else if (! StringUtils.hasText(user.getNickName())){
            throw new SystemException(AppHttpCodeEnum.NICKNAME_NOT_NULL);
        }else if (! StringUtils.hasText(user.getEmail())){
            throw new SystemException(AppHttpCodeEnum.EMAIL_NOT_NULL);
        }

        // 查询用户名是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName,user.getUserName());
        Integer count = userMapper.selectCount(queryWrapper);

        if (count > 0){
            throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
        }
    }
}




